package com.jade.bss.customer.permission.impl;

import java.util.List;
import javax.inject.Named;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import com.jade.bss.customer.CustomerException;
import com.jade.bss.customer.permission.PermissionDao;
import com.jade.bss.customer.permission.PermissionEntry;
import com.jade.bss.customer.permission.PermissionGroup;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;

/**
 * 采用JPA方式实现的权限数据访问接口。
 *
 * @author sky
 * @version 1.0 13-4-18 上午9:56
 */
@Named ("bss_permissionDao")
public class JpaPermissionDao implements PermissionDao
{
    @PersistenceContext (unitName = "default")
    protected EntityManager em;

    @Cacheable (value = "bss.perm.g", key = "#id")
    public PermissionEntry getPermission(int id)
    {
        return em.find(PermissionEntry.class, id);
    }

    @Cacheable (value = "bss.perm.gn", key = "#name")
    public PermissionEntry getPermission(String name)
    {
        String sql = "SELECT perm FROM PermissionEntry perm where name=:name";
        Query query = em.createQuery(sql);
        query.setParameter("name", name);
        try {
            return (PermissionEntry)query.getSingleResult();
        }
        catch (NoResultException ex) {
            return null;
        }
    }

    @SuppressWarnings ("unchecked")
    @Cacheable (value = "bss.perm.l", key = "'all'")
    public List<PermissionEntry> listPermission()
    {
        String sql = "SELECT perm FROM PermissionEntry perm ORDER BY sortCode asc";
        Query query = em.createQuery(sql);
        return query.getResultList();
    }

    @Caching (evict = {@CacheEvict (value = "bss.perm.g", key = "#perm.id"),
                       @CacheEvict (value = "bss.perm.gn", key = "#perm.name"),
                       @CacheEvict (value = "bss.perm.l", allEntries = true)})
    public int addPermission(PermissionEntry perm)
            throws CustomerException
    {
        em.persist(perm);
        return perm.getId();
    }

    @Caching (evict = {@CacheEvict (value = "bss.perm.g", key = "#perm.id"),
                       @CacheEvict (value = "bss.perm.gn", key = "#perm.name"),
                       @CacheEvict (value = "bss.perm.l", allEntries = true)})
    public void updatePermission(PermissionEntry perm)
            throws CustomerException
    {
        em.merge(perm);
    }

    @Caching (evict = {@CacheEvict (value = "bss.perm.g", key = "#id"),
                       @CacheEvict (value = "bss.perm.gn", allEntries = true),
                       @CacheEvict (value = "bss.perm.l", allEntries = true)})
    public void removePermission(int id)
            throws CustomerException
    {
        String sql = "DELETE FROM PermissionEntry WHERE id=:id";
        Query query = em.createQuery(sql);
        query.setParameter("id", id);
        query.executeUpdate();
    }

    @Cacheable (value = "bss.perm.gg", key = "#id")
    public PermissionGroup getGroup(int id)
    {
        return em.find(PermissionGroup.class, id);
    }

    @SuppressWarnings ("unchecked")
    @Cacheable (value = "bss.perm.lg", key = "'all'")
    public List<PermissionGroup> listGroup()
    {
        String sql = "SELECT group FROM PermissionGroup group ORDER BY sortCode asc";
        Query query = em.createQuery(sql);
        return query.getResultList();
    }

    @Caching (evict = {@CacheEvict (value = "bss.perm.gg", key = "#group.id"),
                       @CacheEvict (value = "bss.perm.lg", allEntries = true)})
    public int addGroup(PermissionGroup group)
            throws CustomerException
    {
        em.persist(group);
        return group.getId();
    }

    @Caching (evict = {@CacheEvict (value = "bss.perm.gg", key = "#groupId"),
                       @CacheEvict (value = "bss.perm.lg", allEntries = true)})
    public void removeGroup(int groupId)
            throws CustomerException
    {
        String sql = "DELETE FROM PermissionGroup WHERE id=:id";
        Query query = em.createQuery(sql);
        query.setParameter("id", groupId);
        query.executeUpdate();
    }
}
